package com.cd2cd.code_template.curd.service;

import com.alibaba.fastjson.JSONObject;
import com.cd2cd.code_template.configuration.constants.ServiceCode;
import com.cd2cd.code_template.configuration.exceptions.ServerInternalErrorException;
import com.cd2cd.code_template.util.AppCtxHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

import static com.cd2cd.code_template.curd.annotation.CustomCurdRegistrar.CUSTOM_SERVICE;

@Slf4j
@Service
public final class DispatchService {

    @Resource(name = "CURDService")
    private CURDService curdService;

    public <T> T dispatch(CurdEnum fun, String entity, Map<String, Object> params) {
        try {

            T ret;
            if(CUSTOM_SERVICE.containsKey(entity)) {

                // 调用自定义Service
                String value = CUSTOM_SERVICE.get(entity);
                String[] ss = value.split("\\|");
                String cusName = ss[0];
                String doMain = ss[1];

                Object cusServiceImpl = AppCtxHelper.getBean(cusName);
                Method mm = cusServiceImpl.getClass().getMethod(fun.name(), Object.class, Map.class);

                // obj params
                Class cla = Class.forName(doMain);
                Object claObj = JSONObject.parseObject(JSONObject.toJSONString(params), cla);

                ret = (T) mm.invoke(cusServiceImpl, claObj, params);
            } else {
                Method mm = CURDService.class.getDeclaredMethod(fun.name(), String.class, Map.class);
                ret = (T) mm.invoke(curdService, entity, params);
            }

            return ret;
        } catch (InvocationTargetException e) {
            throw new ServerInternalErrorException(ServiceCode.FAILED, e);
        } catch (Exception e) {
            throw new ServerInternalErrorException(ServiceCode.FAILED, e);
        }
    }

}
